package dao;

import beans.EmployeesBeanRemote;
import beans.EmployeesBeanRemoteHome;
import javax.naming.NamingException;
import wrappers.*;
import exceptions.DatabaseException;
import java.rmi.RemoteException;
import java.util.*;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import views.HighlightElement;
import views.LinkElement;
import views.TextElement;

/**
 *
 * @author Alejandro
 */
public class EmployeeDAO implements BaseDAO {

    EmployeesBeanRemoteHome home;

    public EmployeeDAO() {
        try {
            InitialContext ic = new InitialContext();
            Object objBean = ic.lookup("ejb/beanEmployees");
            home = (EmployeesBeanRemoteHome) PortableRemoteObject.narrow(objBean, EmployeesBeanRemoteHome.class);
        } catch (NamingException ex) {
            throw new RuntimeException(ex);
        }
    }

    @Override
    public void insert(Object obj) throws DatabaseException {
        try {
            EmployeeWrap e = (EmployeeWrap) obj;
            home.create(e.getName(), e.getSurname(), e.getJob(), e.getManager(), e.getDate(), e.getSalary(), e.getDepartment());
        } catch (CreateException ex) {
            throw new DatabaseException(ex);
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        }
    }

    @Override
    public void deleteById(int id) throws DatabaseException {
        try {
            Object o = home.findByPrimaryKey(id);
            EmployeesBeanRemote cbr = (EmployeesBeanRemote) o;
            cbr.remove();
        } catch (RemoveException ex) {
            throw new DatabaseException(ex);
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        } catch (FinderException ex) {
            throw new DatabaseException(ex);
        }catch (EJBException ex) {
            throw new DatabaseException(ex);
        }
    }

    @Override
    public void updateById(Object obj) throws DatabaseException {
        try {
            EmployeeWrap e = (EmployeeWrap) obj;
            EmployeesBeanRemote ebr = (EmployeesBeanRemote) home.findByPrimaryKey(e.getId());
            ebr.setName(e.getName());
            ebr.setSurname(e.getSurname());
            ebr.setJob(e.getJob());
            ebr.setManager(e.getManager());
            ebr.setDate(e.getDate());
            ebr.setSalary(e.getSalary());
            ebr.setDepartment(e.getDepartment());
        } catch (FinderException ex) {
            throw new DatabaseException(ex);
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        }
    }

    @Override
    public List<Object> findAll() throws DatabaseException {
        List<Object> list = new LinkedList<Object>();
        try {
            List<Object> container = (List<Object>) home.findAll();
            for (Object o : container) {
                EmployeesBeanRemote cbr = (EmployeesBeanRemote) o;
                EmployeeWrap ew = new EmployeeWrap((Integer) cbr.getPrimaryKey(), cbr.getName(), cbr.getSurname(), cbr.getJob(), cbr.getManager(), cbr.getDate(), cbr.getSalary(), cbr.getDepartment());
                BaseDAO dao = new EmployeeDAO();
                EmployeeWrap manager = null;
                if (ew.getManager() != 0) {
                    manager = (EmployeeWrap) dao.findById(ew.getManager());
                }
                dao = new DepartmentDAO();
                DepartmentWrap dw = (DepartmentWrap) dao.findById(ew.getDepartment());
                ew.setViewManager(new HighlightElement("manager", (ew.getManager() == 0) ? "No manager" : manager.getName() + " " + manager.getSurname(), (ew.getManager() == 0) ? 0:manager.getId(), EmployeeWrap.IDR));
                ew.setViewDepartment(new LinkElement("department", dw.getTitle(), dw.getCells(), DepartmentWrap.IDR));
                list.add((Object) ew);
            }
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        } catch (FinderException ex) {
            throw new DatabaseException(ex);
        }
        return list;
    }

    @Override
    public Object findById(int id) throws DatabaseException {
        Object obj = new Object();
        try {
            Object o = home.findByPrimaryKey(id);
            EmployeesBeanRemote cbr = (EmployeesBeanRemote) o;
            EmployeeWrap ew = new EmployeeWrap((Integer) cbr.getPrimaryKey(), cbr.getName(), cbr.getSurname(), cbr.getJob(), cbr.getManager(), cbr.getDate(), cbr.getSalary(), cbr.getDepartment());
            BaseDAO dao = new EmployeeDAO();
            EmployeeWrap manager = null;
            if (ew.getManager() != 0) {
                manager = (EmployeeWrap) dao.findById(ew.getManager());
            }
            dao = new DepartmentDAO();
            DepartmentWrap dw = (DepartmentWrap) dao.findById(ew.getDepartment());
            ew.setViewManager(new HighlightElement("manager", (ew.getManager() == 0) ? "No manager" : manager.getName() + " " + manager.getSurname(), (ew.getManager() == 0) ? 0:manager.getId(), EmployeeWrap.IDR));
            ew.setViewDepartment(new LinkElement("department", dw.getTitle(), dw.getCells(), DepartmentWrap.IDR));
            obj = (Object) ew;
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        } catch (FinderException ex) {
            throw new DatabaseException(ex);
        }
        return obj;
    }

    @Override
    public List<Object> findByNameOrSurname(String query) throws DatabaseException {
        List<Object> list = new LinkedList<Object>();

        query = (query + " ");
        List<String> query2 = new LinkedList<String>();
        int j = -2;
        for (int i = 0; i < query.length(); i++) {
            if (query.charAt(i) == ' ' || query.charAt(i) == ',' || query.charAt(i) == ';') {
                if (j == -2) {
                    j += 2;
                }
                if (!query.substring(j, i).equals(" ") && !query.substring(j, i).equals(";") && !query.substring(j, i).equals(",") && !query.substring(j, i).equals("")) {
                    query2.add(query.substring(j, i));
                }
                j = i + 1;
            }
        }
        try {
            List<Integer> listId = new LinkedList<Integer>();
            for (int i = 0; i < query2.size(); i++) {
                List<Object> container = (List<Object>) home.findByNameOrSurname(query2.get(i));
                for (Object o : container) {
                    EmployeesBeanRemote cbr = (EmployeesBeanRemote) o;
                    if (!listId.contains((Integer) cbr.getPrimaryKey())) {
                        listId.add((Integer) cbr.getPrimaryKey());
                        EmployeeWrap ew = new EmployeeWrap((Integer) cbr.getPrimaryKey(), cbr.getName(), cbr.getSurname(), cbr.getJob(), cbr.getManager(), cbr.getDate(), cbr.getSalary(), cbr.getDepartment());
                        BaseDAO dao = new EmployeeDAO();
                        EmployeeWrap manager = null;
                        if (ew.getManager() != 0) {
                            manager = (EmployeeWrap) dao.findById(ew.getManager());
                        }
                        dao = new DepartmentDAO();
                        DepartmentWrap dw = (DepartmentWrap) dao.findById(ew.getDepartment());
                        ew.setViewManager(new HighlightElement("manager", (ew.getManager() == 0) ? "No manager" : manager.getName() + " " + manager.getSurname(), (ew.getManager() == 0) ? 0:manager.getId(), EmployeeWrap.IDR));
                        ew.setViewDepartment(new LinkElement("department", dw.getTitle(), dw.getCells(), DepartmentWrap.IDR));
                        list.add((Object) ew);
                    }
                }
            }
        } catch (RemoteException ex) {
            throw new DatabaseException(ex);
        } catch (FinderException ex) {
            throw new DatabaseException(ex);
        }
        return list;
    }
}
